package com.cskaoyan.service.impl;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.bo.PermissionBo;
import com.cskaoyan.bean.vo.*;
import com.cskaoyan.mapper.*;
import com.cskaoyan.service.SystemService;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author Fantasylkh
 */
@Service
public class SystemServiceImpl implements SystemService {

    @Autowired
    CskaoyanmallRoleMapper cskaoyanmallRoleMapper;

    @Autowired
    CskaoyanmallAdminMapper cskaoyanmallAdminMapper;

    @Autowired
    CskaoyanmallLogMapper logMapper;

    @Autowired
    PermissionMapper permissionMapper;

    @Autowired
    CskaoyanmallUserMapper userMapper;

    @Autowired
    CskaoyanmallGoodsMapper goodsMapper;

    @Autowired
    CskaoyanmallGoodsProductMapper productMapper;

    @Autowired
    CskaoyanmallOrderMapper orderMapper;

    @Override
    public List<RoleOptionsVo> roleOptions() {
        List<RoleOptionsVo> roleOptions = cskaoyanmallRoleMapper.selectRoleOptions( );
        return roleOptions;
    }

    @Override
    public AdminListVo adminList(int page, int limit, String username, String sort, String order) {
        CskaoyanmallAdminExample adminExample = new CskaoyanmallAdminExample( );
        adminExample.setOrderByClause(sort + " " + order);
        if (username != null && !"".equals(username)) {
            CskaoyanmallAdminExample.Criteria criteria = adminExample.createCriteria( );
            criteria.andUsernameLike("%" + username + "%");
        }
        List<CskaoyanmallAdmin> admins = cskaoyanmallAdminMapper.selectAdminListDataByExample(adminExample);
        PageInfo<CskaoyanmallAdmin> adminPageInfo = new PageInfo<>(admins);
        long total = adminPageInfo.getTotal( );
        AdminListVo adminListVo = new AdminListVo( );
        adminListVo.setTotal(total);
        adminListVo.setItems(admins);
        return adminListVo;
    }

    @Transactional
    @Override
    public CskaoyanmallAdmin adminCreate(CskaoyanmallAdmin cskaoyanmallAdmin) {
        Date date = new Date( );
        cskaoyanmallAdmin.setAddTime(date);
        cskaoyanmallAdmin.setUpdateTime(date);
        cskaoyanmallAdmin.setDeleted(false);
        //todo
        //密码加密
        Md5Hash md5Hash = new Md5Hash(cskaoyanmallAdmin.getPassword());
        md5Hash.setIterations(1024);
        cskaoyanmallAdmin.setPassword(md5Hash.toHex());
        int effect = cskaoyanmallAdminMapper.insert(cskaoyanmallAdmin);
        if (effect == 0) {
            return null;
        }
        int id = cskaoyanmallAdminMapper.selectIdByUsername(cskaoyanmallAdmin);
        cskaoyanmallAdmin.setId(id);
        return cskaoyanmallAdmin;
    }

    @Override
    public int deleteAdmin(CskaoyanmallAdmin admin) {
        int effect = cskaoyanmallAdminMapper.deleteByPrimaryKey(admin.getId( ));
        return effect;
    }

    @Override
    public CskaoyanmallAdmin updateAdmin(CskaoyanmallAdmin admin) {
        CskaoyanmallAdmin updateAdmin = null;
        admin.setUpdateTime(new Date());
        Md5Hash md5Hash = new Md5Hash(admin.getPassword());
        md5Hash.setIterations(1024);
        admin.setPassword(md5Hash.toHex());
        int effect = cskaoyanmallAdminMapper.updateByPrimaryKeySelective(admin);
        updateAdmin = cskaoyanmallAdminMapper.selectUpdateAdminById(admin.getId( ));
        return updateAdmin;
    }

    @Override
    public RoleListVo roleList(int page, int limit, String name, String sort, String order) {
        CskaoyanmallRoleExample roleExample = new CskaoyanmallRoleExample( );
        roleExample.setOrderByClause(sort + " " + order);
        if (name != null && !"".equals(name)) {
            CskaoyanmallRoleExample.Criteria criteria = roleExample.createCriteria( );
            criteria.andNameLike("%" + name + "%");
        }
        List<CskaoyanmallRole> roles = cskaoyanmallRoleMapper.selectByExample(roleExample);
        PageInfo<CskaoyanmallRole> pageInfo = new PageInfo<>(roles);
        long total = pageInfo.getTotal( );
        RoleListVo roleListVo = new RoleListVo( );
        roleListVo.setTotal(total);
        roleListVo.setItems(roles);
        return roleListVo;
    }

    @Override
    public CskaoyanmallRole roleCreate(CskaoyanmallRole role) {

        Integer effect = cskaoyanmallRoleMapper.isExistByName(role.getName( ));
        if (effect != null) {
            return null;
        }
        role.setAddTime(new Date( ));
        role.setUpdateTime(new Date( ));
        role.setEnabled(true);
        role.setDeleted(false);
        int insert = cskaoyanmallRoleMapper.insertWithNameAndDesc(role);
        if (insert == 1) {
            Integer id = cskaoyanmallRoleMapper.isExistByName(role.getName( ));
            role.setId(id);
            return role;
        }
        return null;
    }

    @Override
    public int roleUpdate(CskaoyanmallRole role) {
        if (role.getName( ) == null || "".equals(role.getName( ))) {
            return 0;
        }
        role.setUpdateTime(new Date( ));
        int effect = cskaoyanmallRoleMapper.updateByRole(role);
        return effect;
    }

    @Override
    public int roleDelete(CskaoyanmallRole role) {
        int roleId = role.getId( );
        boolean flag = false;
        List<CskaoyanmallAdmin> admins = cskaoyanmallAdminMapper.selectByExample(new CskaoyanmallAdminExample( ));
        for (CskaoyanmallAdmin admin : admins) {
            Integer[] roleIds = admin.getRoleIds( );
            for (int i = 0; i < roleIds.length; i++) {
                if (roleId == roleIds[i]) {
                    flag = true;
                    break;
                }
            }
        }
        if (flag) {
            return 0;
        }
        int effect = cskaoyanmallRoleMapper.deleteByPrimaryKey(roleId);
        return effect;
    }

    @Override
    public int selectName(CskaoyanmallAdmin cskaoyanmallAdmin) {
        int effect = cskaoyanmallAdminMapper.selectHaveName(cskaoyanmallAdmin);
        return effect;
    }

    @Override
    public LogListVo logList(int page, int limit, String name, String sort, String order) {
        CskaoyanmallLogExample logExample = new CskaoyanmallLogExample( );
        logExample.setOrderByClause(sort + " " + order);
        if (name != null && !"".equals(name)) {
            CskaoyanmallLogExample.Criteria criteria = logExample.createCriteria( );
            criteria.andAdminLike("%" + name + "%");
        }
        List<CskaoyanmallLog> logs = logMapper.selectByExample(logExample);
        PageInfo<CskaoyanmallLog> pageInfo = new PageInfo<>(logs);
        long total = pageInfo.getTotal( );
        LogListVo logListVo = new LogListVo( );
        logListVo.setTotal(total);
        logListVo.setItems(logs);
        return logListVo;
    }

    @Override
    public RolePermissionsVo rolePermissions(int roleId) {
        List<RolePermissionsData> permissionsDataList = getAllPermissions( );
        String[] api = permissionMapper.selectApiByRoleId(roleId);
        RolePermissionsVo vo = new RolePermissionsVo( );
        vo.setAssignedPermissions(api);
        vo.setSystemPermissions(permissionsDataList);
        return vo;
    }

    @Override
    public void permissions(PermissionBo bo) {
        int id = bo.getRoleId( );
        permissionMapper.deleteRelation(id);
        List<PermissionRelation> relations = new ArrayList<>( );
        for (String permission : bo.getPermissions( )) {
            PermissionRelation permissionRelation = new PermissionRelation( );
            permissionRelation.setRoleId(id);
            String api = permissionMapper.selectApiByPermission(permission);
            permissionRelation.setPermission(api);
            relations.add(permissionRelation);
        }
        if (bo.getPermissions().length == 89) {
            PermissionRelation permissionRelation = new PermissionRelation();
            permissionRelation.setRoleId(id);
            permissionRelation.setPermission("*");
            relations.add(permissionRelation);
        }
        permissionMapper.insertPermission(relations);
    }

    @Override
    public TotalVo selectTotalNum() {
        TotalVo totalVo = new TotalVo();
        Long userTotal = userMapper.selectNum();
        Long goodsTotal = goodsMapper.selectNum();
        Long productTotal = productMapper.selectNum();
        Long orderTotal = orderMapper.selectNum();

        totalVo.setGoodsTotal(goodsTotal);
        totalVo.setProductTotal(productTotal);
        totalVo.setOrderTotal(orderTotal);
        totalVo.setUserTotal(userTotal);
        return totalVo;
    }

    private List<RolePermissionsData> getAllPermissions() {
        List<RolePermissionsData> dataFathers = permissionMapper.selectAllPermissionFather( );
        for (RolePermissionsData dataFather : dataFathers) {
            List<RolePermissionsData> dataChildren = permissionMapper.selectChildrenById(dataFather.getKid( ));
            dataFather.setKid(null);
            for (RolePermissionsData dataChild : dataChildren) {
                List<RolePermissionsApi> dataApi = permissionMapper.selectApiByChildId(dataChild.getKid( ));
                dataChild.setChildren(dataApi);
                dataChild.setKid(null);
            }
            dataFather.setChildren(dataChildren);
        }
        return dataFathers;
    }
}
